home *** CD-ROM | disk | FTP | other *** search
/ Java Developer's Companion / Java Developer's Companion.iso / documentation / tutorial / ui / drawing / example / DoubleBuffer.java < prev    next >
Encoding:
Java Source  |  1997-07-13  |  5.9 KB  |  205 lines

  1. /*
  2.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for NON-COMMERCIAL purposes and without
  6.  * fee is hereby granted provided that this copyright notice
  7.  * appears in all copies. Please refer to the file "copyright.html"
  8.  * for further important copyright and licensing information.
  9.  *
  10.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  11.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  14.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  15.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  16.  */
  17. import java.awt.*;
  18. import java.applet.Applet;
  19.  
  20. /* 
  21.  * This applet animates graphics that it generates.  This example
  22.  * eliminates flashing by double buffering.
  23.  */
  24.  
  25. public class DoubleBuffer extends Applet implements Runnable {
  26.     int frameNumber = -1;
  27.     int delay;
  28.     Thread animatorThread;
  29.     boolean frozen = false;
  30.  
  31.     int squareSize = 20;
  32.     boolean fillColumnTop = true;
  33.  
  34.     Dimension offDimension;
  35.     Image offImage;
  36.     Graphics offGraphics;
  37.  
  38.     public void init() {
  39.         String str;
  40.         int fps = 10;
  41.  
  42.         //How many milliseconds between frames?
  43.         str = getParameter("fps");
  44.         try {
  45.             if (str != null) {
  46.                 fps = Integer.parseInt(str);
  47.             }
  48.         } catch (Exception e) {}
  49.         delay = (fps > 0) ? (1000 / fps) : 100;
  50.  
  51.         //How many pixels wide is each square?
  52.         str = getParameter("squareWidth");
  53.         try {
  54.             if (str != null) {
  55.                 squareSize = Integer.parseInt(str);
  56.             }
  57.         } catch (Exception e) {}
  58.     }
  59.  
  60.     public void start() {
  61.         if (frozen) {
  62.             //Do nothing.  The user has requested that we
  63.             //stop changing the image.
  64.         } else {
  65.             //Start animating!
  66.             if (animatorThread == null) {
  67.                 animatorThread = new Thread(this);
  68.             }
  69.             animatorThread.start();
  70.         }
  71.     }
  72.  
  73.     public void stop() {
  74.         //Stop the animating thread.
  75.         animatorThread = null;
  76.  
  77.         //Get rid of the objects necessary for double buffering.
  78.         offGraphics = null;
  79.         offImage = null;
  80.     }
  81.  
  82.     public boolean mouseDown(Event e, int x, int y) {
  83.         if (frozen) {
  84.             frozen = false;
  85.             start();
  86.         } else {
  87.             frozen = true;
  88.  
  89.             //Instead of calling stop(), which destroys the
  90.             //backbuffer, just stop the animating thread.
  91.             animatorThread = null;
  92.         }
  93.         return true;
  94.     }
  95.  
  96.     public void run() {
  97.         //Just to be nice, lower this thread's priority
  98.         //so it can't interfere with other processing going on.
  99.         Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
  100.  
  101.         //Remember the starting time.
  102.         long startTime = System.currentTimeMillis();
  103.  
  104.         //This is the animation loop.
  105.         while (Thread.currentThread() == animatorThread) {
  106.             //Advance the animation frame.
  107.             frameNumber++;
  108.  
  109.             //Display it.
  110.             repaint();
  111.  
  112.             //Delay depending on how far we are behind.
  113.             try {
  114.                 startTime += delay;
  115.                 Thread.sleep(Math.max(0, 
  116.                                       startTime-System.currentTimeMillis()));
  117.             } catch (InterruptedException e) {
  118.                 break;
  119.             }
  120.         }
  121.     }
  122.  
  123.     public void paint(Graphics g) {
  124.         update(g);
  125.     }
  126.  
  127.     public void update(Graphics g) {
  128.         Dimension d = size();
  129.         boolean fillSquare;
  130.         boolean fillNextFrame;
  131.         int rowWidth = 0;
  132.         int x = 0, y = 0;
  133.         int w, h;
  134.         int tmp;
  135.  
  136.         //Create the offscreen graphics context, if no good one exists.
  137.         if ( (offGraphics == null)
  138.           || (d.width != offDimension.width)
  139.           || (d.height != offDimension.height) ) {
  140.             offDimension = d;
  141.             offImage = createImage(d.width, d.height);
  142.             offGraphics = offImage.getGraphics();
  143.         }
  144.  
  145.         //Erase the previous image.
  146.         offGraphics.setColor(getBackground());
  147.         offGraphics.fillRect(0, 0, d.width, d.height);
  148.         offGraphics.setColor(Color.black);
  149.  
  150.         //Set width of first "square". Decide whether to fill it.
  151.         fillSquare = fillColumnTop;
  152.         fillColumnTop = !fillColumnTop;
  153.         tmp = frameNumber % squareSize;
  154.         if (tmp == 0) {
  155.             w = squareSize;
  156.             fillNextFrame = !fillSquare;
  157.         } else {
  158.             w = tmp;
  159.             fillNextFrame = fillSquare;
  160.         }
  161.  
  162.         //Draw from left to right.
  163.         while (x < d.width) {
  164.             int colHeight = 0;
  165.  
  166.             //Draw the column.
  167.             while (y < d.height) {
  168.                 colHeight += squareSize;
  169.  
  170.                 //If we don't have room for a full square, cut if off.
  171.                 if (colHeight > d.height) {
  172.                     h = d.height - y;
  173.                 } else {
  174.                     h = squareSize;
  175.                 }
  176.  
  177.                 //Draw the rectangle if necessary.
  178.                 if (fillSquare) {
  179.                     offGraphics.fillRect(x, y, w, h);
  180.                     fillSquare = false;
  181.                 } else {
  182.                     fillSquare = true;
  183.                 } 
  184.  
  185.                 y += h;
  186.             } //while y
  187.  
  188.             //Determine x, y, and w for the next go around.
  189.             x += w;
  190.             y = 0;
  191.             w = squareSize;
  192.             rowWidth += w;
  193.             if (rowWidth > d.width) {
  194.                 w = d.width - x;
  195.             }
  196.             fillSquare = fillColumnTop;
  197.             fillColumnTop = !fillColumnTop;
  198.         } //while x
  199.         fillColumnTop = fillNextFrame;
  200.  
  201.         //Paint the image onto the screen.
  202.         g.drawImage(offImage, 0, 0, this);
  203.     }
  204. }
  205.